////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    SpinTestData.h                                               //
//  Developer:   Tommy Riddle                                                 //
//  Create date: 04/29/2005                                                   //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: Class that accumulates data during spin testing.             //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2005 - Realtime Gaming.  All rights reserved.         //
////////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_SPINTESTDATA_H__737B3062_7E49_448A_A100_AD18F4BD306C__INCLUDED_)
#define AFX_SPINTESTDATA_H__737B3062_7E49_448A_A100_AD18F4BD306C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class SlotConnection;
class SlotGuts;
class SlotSpin;

#include "SpinTestMessage.h"

////////////////////////////////////////////////////////////////////////////////
//
//	CSpinTestData
//
//	This class is used by the SlotConnection class to accumulate statistics
//  about the slot machine during spin testing.
//
////////////////////////////////////////////////////////////////////////////////

class CSpinTestData
{
public:
	CSpinTestData();
	virtual ~CSpinTestData();

	// Diagnostic function that checks to make sure that the totals are correct.
	void VerifyTotals();

	// This function has to be called once after construction and before the
	// object can be used to accumulate data.
	void Initialize( uint8 nMaxGameMode, uint8 nMaxPayoutType, uint8 nMaxBonusGameType, uint8 nSubstNoteID, uint8 nNumClientDataSets );

	// This function is called to store the new client data set contained in
	// the protocol message.
	bool8 AddClientDataSet( const CSpinTestClientDataMessage* pMsg );

	// This function is called to reset the object to its initial state before
	// each batch of spins.
	void Reset();

	// This function sends the next set of client data to the gut.
	void SendClientData( SlotGuts* pGuts );

	// This function is called to send the summary data packet to the client.
	void SendSummaryData( SlotConnection* pConnection );

	// This function is called to send a game mode summary data packet to the client.
	void SendGameModeSummaryData( SlotConnection* pConnection, uint8 nGameMode );

	// This function is called to send a payout type detail data packet to the client.
	void SendPayoutTypeDetailData( SlotConnection* pConnection, uint8 nGameMode, uint8 nPayoutType );

	// This function is called to send a bonus game type detail data packet to the client.
	void SendBonusGameTypeDetailData( SlotConnection* pConnection, uint8 nBonusGameType );

	// This function is called after each spin to accumulate the results.
	void AccumulateSpinResults( uint32 nLines, uint32 nBetPerLine, bool bPaidSpinCompleted, SlotSpin* spin );

	// This function gets the total number of paid lines played during the batch of spins.
	uint32 GetNumPaidLinesPlayed() const;

private:
	// This is a helper function that accumulates results for a specific payout.
	void AccumulatePayout( uint8 nGameMode, uint8 nPayoutType, bool8 bSubst, uint32 nTotalPayout );

	// This is a helper function that accumulates results for a bonus game.
	void AccumulateBonusGame( uint8 nBonusGameType, uint32 nTotalPayout );

	// This is a helper function that accumulates results for a progessive win.
	void AccumulateProgressive( uint32 nTotalPayout );

	// This is a nested helper class that stores all of the data needed to make
	// one call to the SlotGuts::processClientData function.
	class CClientDataSet
	{
	public:
		CClientDataSet( const CSpinTestClientDataMessage* pMsg );
		virtual ~CClientDataSet();

		// The bonus game type to be passed to SlotGuts::processClientData.
		uint8 m_nBonusGameType;

		// The number of items in the data array.
		int32 m_nDataCount;

		// The array of client data values.
		int32* m_aData;
	};

	// This is a nested helper class that stores detail data for a single payout type
	// or bonus game type.
	class CDetailData
	{
	public:
		CDetailData();

		// This function is called to reset the object to its initial state
		// before each batch of spins.
		void Reset();

		// This function is called to add the passed in payout to the accumulated total.
		void AccumulatePayout( uint32 nTotalPayout );

		// The number of times that this payout type or bonus game type hit.
		uint32 m_nHits;

		// The total payout for this payout type or bonus game type.
		uint32 m_nTotalPayout;
	};

	// This is a nested helper class that stores data for a single game mode.
	class CGameModeData
	{
	public:
		CGameModeData();
		virtual ~CGameModeData();

		// Diagnostic function that checks to make sure that the total is correct.
		void VerifyTotal();

		// This function has to be called once after construction and before the
		// object can be used to accumulate data.
		void Initialize( uint8 nMaxPayoutType );

		// This function is called to reset the object to its initial state
		// before each batch of spins.
		void Reset();

		// This function is called to send a game mode summary data packet to the client.
		void SendSummaryData( SlotConnection* pConnection );

		// This function is called to send a payout type detail data packet to the client.
		void SendPayoutTypeDetailData( SlotConnection* pConnection, uint8 nPayoutType );

		// This function is called to accumulate results for a specific payout
		// type.
		void AccumulatePayout( uint8 nPayoutType, bool8 bSubst, uint32 nTotalPayout );

		// The number of payout types in this game mode.  The size of the two
		// payout data arrays.
		uint8 m_nNumPayoutTypes;

		// An array of detail data objects used to accumulate results when the
		// payout did not have a substitution.
		CDetailData* m_aPayoutDataNoSubst;

		// An array of detail data objects used to accumulate results when the
		// payout did have a substitution.
		CDetailData* m_aPayoutDataWithSubst;

		// The total payout for this game mode.
		uint32 m_nTotalPayout;

		// The number of times this game mode was triggered.
		uint32 m_nNumTriggers;
	};

	// The number of client data set pointers received and currently stored in
	// the array.
	uint8 m_nNumClientDataSetsReceived;

	// The number of client data set pointers allocated in the array.
	uint8 m_nNumClientDataSetsAllocated;

	// The next client data set to be sent to SlotGuts::processClientData;
	uint8 m_nCurrentClientDataSet;

	// The array of pointers to client data sets.
	CClientDataSet** m_apClientDataSets;

	// The number of game modes.  The size of the game mode data array.
	uint8 m_nNumGameModes;

	// The game mode from the previous spin.  Used to see if a feature was triggered.
	uint8 m_nPreviousGameMode;

	// The sum of the payouts squared for each paid game.  Used to calculate the true
	// standard deviation of the sample spins.
	double m_dSumPayoutsSquared;

	// The total payout of the current paid spin, including all free games.
	double m_dCurrentPaidSpinPayout;

	// The note ID that the slot machine uses to indicate that the payout had
	// a substitution.
	uint8 m_nSubstNoteID;

	// The array of game mode data objects.
	CGameModeData* m_aGameModeData;

	// The number of bonus game types for this slot machine.  The size of the
	// bonus game data array.
	uint8 m_nNumBonusGameTypes;

	// An array of detail data objects used to accumulate results for each
	// bonus game type.
	CDetailData* m_aBonusGameData;

	// The total amount of money bet during the batch of spins, in base currency
	// units (pennies for USD).
	uint32 m_nTotalBet;

	// The total payout during the batch of spins in base currency units,
	// including the payout from every game mode and from progressives.
	uint32 m_nTotalPayout;

	// The total payout from progressives during the batch of spins, in base
	// currency units.
	uint32 m_nTotalProgressivePayout;

	// The total number of lines played during the batch of spins, including
	// both paid lines and free lines.
	uint32 m_nTotalLinesPlayed;

	// The total number of paid lines played during the batch of spins.
	uint32 m_nPaidLinesPlayed;

	// The total number of free lines played during the batch of spins.
	uint32 m_nFreeLinesPlayed;
};

#endif // !defined(AFX_SPINTESTDATA_H__737B3062_7E49_448A_A100_AD18F4BD306C__INCLUDED_)
